Programmierung von CAx-Systemen

David Straub

CAx-Programmierung – D. Straub

Gliederung

  1. Einführung
  2. Topologie
  3. Grundformen
  4. Kurven
  5. Freiformgeometrie
  6. Profile
  7. Codequalität
  8. Datenaustausch
  9. Robustheit
  10. Simulation
  11. Optimierung
CAx-Programmierung – D. Straub

Freiformgeometrie

  • Von Kontrollpunkten zu Freiformkurven: Bézier → B-Spline → NURBS
  • Stetigkeit: C0C^0, G1G^1, G2G^2 – und wo sie wirklich zählt
  • Freiformflächen: was Loft & Co. eigentlich erzeugen

Durchgängiges Beispiel: das Kühlkanal-Profil – Einlass- und Auslass-Querschnitt als Spline

CAx-Programmierung – D. Straub

Rückblick: die analytische Familie ist zu klein

Letzte Woche: schon der Versatz einer Ellipse war keine Ellipse mehr (OFFSET).

Der Kühlkanal des Moduls braucht ein frei geformtes Profil – über Linie, Kreis und Ellipse hinaus:

  • Bisher: Profile aus analytischen Kurven
  • Heute: ein frei geformtes, glattes Profil

Frage: Wie beschreibt man eine beliebige glatte Kurve mathematisch?

CAx-Programmierung – D. Straub

Theorie A: Von Kontrollpunkten zu B-Splines

CAx-Programmierung – D. Straub

Warum Polynome – aber niedrigen Grades?

Eine Kurve ist C(u)=(x(u),y(u),z(u))\mathbf{C}(u) = (x(u), y(u), z(u)) – welche Funktion?

Ansatz Problem
Lineare Interpolation Knick an jedem Stützpunkt
Sinus/Kosinus schwer zu verketten, teuer
Ein Polynom hohen Grades Runge-Phänomen: Oszillation
Stückweise Polynome niedrigen Grades ✓ flexibel, stabil, lokal steuerbar

→ Alle Freiformkurven (Bézier, B-Spline, NURBS) sind stückweise Polynome niedrigen Grades.

CAx-Programmierung – D. Straub

Der naive Weg: Potenzbasis

Koordinaten direkt als Polynom in uu:

C(u)=a0+a1u+a2u2++anun\mathbf{C}(u) = \mathbf{a}_0 + \mathbf{a}_1 u + \mathbf{a}_2 u^2 + \cdots + \mathbf{a}_n u^n

Unbrauchbar in der Praxis:

  • Kein geometrischer Bezug: aus a3\mathbf{a}_3 liest man den Kurvenverlauf nicht ab
  • Numerisch empfindlich bei hohem Grad
  • Ändern = Gleichungssystem lösen, nicht per Hand

→ Gesucht: eine Basis, deren Parameter selbst Punkte im Raum sind.

CAx-Programmierung – D. Straub

Bézier: Kontrollpunkte statt Koeffizienten

Renault, 1962 (Karosseriedesign). Kurve direkt über n+1n+1 Kontrollpunkte:

C(u)=i=0nBi,n(u)Pi,u[0,1]\mathbf{C}(u) = \sum_{i=0}^{n} B_{i,n}(u)\, \mathbf{P}_i, \quad u \in [0,1]

  • Bi,nB_{i,n}: Bernstein-Basis – nicht-negativ, iBi,n=1\sum_i B_{i,n} = 1
  • C(u)\mathbf{C}(u) ist eine Konvexkombination → Kurve liegt in der konvexen Hülle
  • Läuft durch P0\mathbf{P}_0 und Pn\mathbf{P}_n; Tangente in P0\mathbf{P}_0: Richtung P1P0\mathbf{P}_1 - \mathbf{P}_0
CAx-Programmierung – D. Straub

Die Grenzen der einzelnen Bézier-Kurve

Eine einzelne Bézier-Kurve über alle Punkte hat zwei Schwächen:

  • Grad = Punktzahl − 1: 20 Punkte → Grad 19 → numerisch instabil, wellig
  • Globale Kontrolle: jeder Punkt beeinflusst die ganze Kurve – kein lokales Anpassen
CAx-Programmierung – D. Straub

Stückweise Bézier: Übergänge von Hand

Ausweg: die Kurve in Segmente teilen, jedes ein Bézier-Stück niedrigen Grades. Aber wie glatt müssen die Übergänge sein?

Bedingung Effekt fixiert
C0C^0 kein Spalt a3=b0\mathbf{a}_3 = \mathbf{b}_0
C1C^1 glatte Tangente + 1 Punkt
C2C^2 glatte Krümmung + 1 Punkt

→ Bei C2C^2 sind 3 von 4 Kontrollpunkten je Segment gebunden – bei vielen Segmenten mühsam von Hand.

Interaktiv: Piecewise Bézier Editor – Segmente ziehen und die Übergänge selbst verwalten

CAx-Programmierung – D. Straub

Der B-Spline: überlappende Fenster

Der B-Spline nimmt diese Buchhaltung ab: benachbarte Spannen teilen sich alle Kontrollpunkte bis auf einen.

  • Eine Bézier-Kurve: eine Spanne, jeder Punkt wirkt überall
  • Stückweise Bézier: eigene Punkte je Spanne, jeder Übergang von Hand
  • B-Spline: überlappende Spannen → Stetigkeit entsteht von selbst

→ Automatische Stetigkeit und lokale Kontrolle, ohne Übergangsgleichungen.

CAx-Programmierung – D. Straub

Die B-Spline-Formel

C(u)=i=0nPiNi,k(u)\mathbf{C}(u) = \sum_{i=0}^{n} \mathbf{P}_i\, N_{i,k}(u)

  • Pi\mathbf{P}_i – die n+1n+1 Kontrollpunkte (die Griffe)
  • Ni,k(u)N_{i,k}(u)Basisfunktionen der Ordnung kk (Grad k1k-1): das Gewicht, mit dem Pi\mathbf{P}_i beim Parameter uu zieht
  • jede Ni,kN_{i,k} ist nur über ein Fenster ungleich null → lokale Kontrolle (rechts: Bézier global, B-Spline lokal)
  • iNi,k(u)=1\sum_i N_{i,k}(u) = 1 → Konvexkombination wie bei Bézier
CAx-Programmierung – D. Straub

Der Knotenvektor

Was die Ni,kN_{i,k} überhaupt festlegt, ist der Knotenvektor:

T=(t0t1tm)T = (t_0 \le t_1 \le \dots \le t_m)

  • eine nicht-fallende Folge von Parameterwerten (die „Knoten"); sie teilen die Parameterachse in Spannen und legen fest, wo jede Ni,kN_{i,k} ihr Fenster hat
  • bei einfachen Knoten: Ordnung kkCk2C^{k-2} (kubisch, k=4k=4C2C^2, der CAD-Standard)
  • Multiplizität: einen Knoten mehrfach setzen senkt dort die Stetigkeit; volle Multiplizität → Knick

Interaktiv: B-Spline-Editor – Knoten-Ticks ziehen, Multiplizität erhöhen und den Knick entstehen sehen

CAx-Programmierung – D. Straub

Interpolation: Kurve durch gegebene Punkte

Kontrollpunkte sind Hebel – die Kurve läuft an ihnen vorbei. Oft liegen die Punkte aber fest: gemessen, aus einer Tabelle, aus einer Formel. Dann soll die Kurve genau hindurch.

Das ist Interpolation: Zu den Datenpunkten Qi\mathbf{Q}_i löst der Kern die passenden Kontrollpunkte Pi\mathbf{P}_i – ein lineares Gleichungssystem.

Rechts: die Kurve trifft jeden Datenpunkt (rot), die dafür berechneten Kontrollpunkte (blau) liegen woanders.

CAx-Programmierung – D. Straub

Praktikum A: Kühlkanal-Querschnitt als Spline

CAx-Programmierung – D. Straub

Aufgabe 1: Spline durch Punkte

Legen Sie eine Kurve durch fünf frei gewählte Punkte – einmal als Spline, einmal als Polyline.

  1. Trifft die Spline-Kurve den ersten und letzten Punkt exakt?
  2. Wo liegt der Unterschied zwischen beiden – geometrisch und im geomType?

Hinweise: cf.spline, cf.polyline, .geomType(), .positionAt(0.0) / .positionAt(1.0)

CAx-Programmierung – D. Straub

Aufgabe 2: Der Einlass-Querschnitt

Bauen Sie den Kühlkanal-Querschnitt als geschlossene, glatte Kurve aus etwa acht Punkten (Breite ≈ 50 mm, Höhe ≈ 14 mm) und daraus eine Fläche.

  1. Prüfen Sie IsClosed() und den Flächeninhalt.
  2. Vergleichen Sie mit periodic=False und dupliziertem Endpunkt: Wo entsteht der Knick?

Hinweise: cf.spline(*pts, periodic=True) – den Startpunkt am Ende nicht wiederholen; cf.face, .IsClosed(), .Area()

CAx-Programmierung – D. Straub

Theorie B: NURBS, Stetigkeit, Flächen

CAx-Programmierung – D. Straub

NURBS: warum ein B-Spline nicht genügt

Kann ein B-Spline einen exakten Kreis darstellen?

Nein. Wäre C(t)\mathbf{C}(t) ein Polynom mit x(t)2+y(t)2=R2x(t)^2 + y(t)^2 = R^2 für alle tt, müssten alle nicht-konstanten Terme verschwinden – die Kurve wäre ein Punkt. Widerspruch.

Lösung – Gewichte hi>0h_i > 0 (rationale Kurve):

C(u)=ihiPiNi,k(u)ihiNi,k(u)\mathbf{C}(u) = \frac{\sum_i h_i\, \mathbf{P}_i\, N_{i,k}(u)}{\sum_i h_i\, N_{i,k}(u)}

Viertelkreis exakt: 3 Punkte, Gewichte 1,22,11, \tfrac{\sqrt2}{2}, 1. Rechts: gleiche Punkte, ein Gewicht – B-Spline wölbt sich, NURBS trifft den Bogen exakt.

CAx-Programmierung – D. Straub

NURBS ist die universelle Darstellung

Linie ⊂ Bézier ⊂ B-Spline ⊂ NURBS

Jede analytische Kurve ist ein NURBS-Spezialfall → einheitlicher Standard (CATIA, SolidWorks, NX, OCCT).

geomType Bedeutung
LINE, CIRCLE, ELLIPSE analytisch, exakt gespeichert
BSPLINE Freiformkurve (B-Spline / NURBS – dieselbe Klasse)

Beim STEP-Import erscheinen Freiformkurven als BSPLINE, teils sogar ursprüngliche Kreise – je nach exportierendem System.

CAx-Programmierung – D. Straub

Stetigkeit: C0C^0, G1G^1, G2G^2

Beim Aneinanderstoßen von Kurven/Flächen zählt die Anschlussbedingung:

Klasse stimmt überein sichtbar
C0C^0 Position Knick erlaubt
G1G^1 Tangentenrichtung glatt fürs Auge
G2G^2 Krümmung reflexionsglatt

Rechts: Linie trifft Kreisbogen tangential – G1G^1, kein Knick. Der Krümmungskamm springt aber am Übergang von 0 auf 1/R1/R: nur G1G^1, nicht G2G^2.

CAx-Programmierung – D. Straub

Wo Stetigkeit wirklich zählt

Nicht überall ist G2G^2 nötig – aber wo, dann hart:

Anwendung warum G2G^2
Optik / Design Lichtreflexion folgt der Krümmung – ein Sprung ist sichtbar
Fertigung Fräserbahn = Versatz der Fläche – Krümmungssprung → Maßfehler
Aerodynamik Grenzschicht reagiert auf Krümmungsänderung
Kontakt / Implantate Spannungsspitze genau am Krümmungssprung

Faustregel: C0C^0 für boolesche Kanten, G1G^1 für fillet, G2G^2 für Karosserie/Strömung.

CAx-Programmierung – D. Straub

Von Kurven zu Flächen

Eine Fläche hat zwei Parameter:

S(u,v)=(x(u,v)y(u,v)z(u,v))\mathbf{S}(u, v) = \begin{pmatrix} x(u,v) \\ y(u,v) \\ z(u,v) \end{pmatrix}

Alles von den Kurven gilt eine Dimension höher weiter. Die analytische Familie (Ebene, Zylinder, Kegel, Kugel, Torus) reicht für Standardkörper – der Rest wird BSPLINE.

Die Normale ist Su×Sv\mathbf{S}_u \times \mathbf{S}_v (normiert) – genau das, was normalAt() aus Einheit 2 berechnet.

CAx-Programmierung – D. Straub

Was Loft erzeugt: ruled vs. glatt

Das Eingangsprofil bestimmt die Ausgabefläche. Loft hat zusätzlich eine Stetigkeits-Entscheidung:

secs = [cf.wire(cf.circle(10)),
        cf.wire(cf.circle(16)).translate((0,0,25)),
        cf.wire(cf.circle(10)).translate((0,0,50))]

cf.loft(secs, ruled=True)    # ['CONE', 'CONE'] – Knick in der Mitte
cf.loft(secs, ruled=False)   # ['BSPLINE'] – eine glatte Fläche

ruled=True: gerade Verbindung, C0C^0 (Bézier-Analogon). Default glatt: eine B-Spline-Fläche über alle Schnitte.

CAx-Programmierung – D. Straub

fillet ist ein Flächenerzeuger

box = cf.box(50, 30, 20)
box_f = cf.fillet(box, box.edges(), 3.0)
print(sorted(set(f.geomType() for f in box_f.Faces())))
# ['CYLINDER', 'PLANE', 'SPHERE']
  • Zylinderfläche entlang jeder gerundeten Kante, Kugelfläche in jeder Ecke
  • Beide tangential (G1G^1) an die Ebenen – aber die Krümmung springt: nicht G2G^2

Das ist dieselbe Verrundung wie seit Einheit 1 – jetzt sehen Sie, welche Flächen sie erzeugt.

CAx-Programmierung – D. Straub

Praktikum B: Auslass-Querschnitt und Kurveneigenschaften

CAx-Programmierung – D. Straub

Aufgabe 3: Der Auslass-Querschnitt

Der Kanal verjüngt sich zum Auslass (gleichmäßige Flussverteilung). Bauen Sie einen zweiten, kleineren Querschnitt – gleiches Prinzip, kleinere Maße:

auslass = [(22,0,0),(13,4,0),(0,5,0),(-10,3,0),
           (-15,0,0),(-10,-3,0),(0,-5,0),(13,-4,0)]
profil_auslass = cf.spline(*auslass, periodic=True)
  1. Erzeugen Sie beide Profile (Einlass aus Aufgabe 2, Auslass hier) und legen Sie sie in verschiedene Höhen (.translate((0,0,z))).
  2. Damit ist der Kanal vorbereitet: aus den beiden Querschnitten wird per Loft der verjüngte Kühlkanal – speichern Sie beide.
CAx-Programmierung – D. Straub

Aufgabe 4: Kurveneigenschaften auslesen

  1. profil.geomType() für Ihre Splines – und für einen Kreis (cf.circle). Was fällt auf?
  2. Versetzen Sie das geschlossene Profil um 3 (cf.offset2D(cf.wire(profil), 3.0)) und lesen Sie die geomType-Werte der Ergebniskanten. Analytisch oder nicht?
  3. (Zusatz) Tasten Sie curvatureAt(t) entlang eines Profils ab – wo ist die Krümmung am größten (Nase vs. flanke)?
CAx-Programmierung – D. Straub

Abschluss

CAx-Programmierung – D. Straub

Leseauftrag & Ausblick

  • Leseauftrag: Buch Kapitel 6
  • Wer mehr will: einen Loft der beiden Profile schon vorab probieren (cf.loft) – und ruled=True vs. False vergleichen
  • Nächste Woche: Profile – Sweep und Loft: die beiden Querschnitte werden zum verjüngten Kühlkanal (Loft), der Kanal läuft als Sweep durch die Platte
  • Bis dahin: w05/ (beide Profile) committet und gepusht
CAx-Programmierung – D. Straub